package info.nightbrest.agt.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.event.shared.SimpleEventBus;
import info.nightbrest.agt.client.event.UserLoggedInEvent;
import info.nightbrest.agt.client.view.AgtShell;
import info.nightbrest.agt.client.view.LoginPanelView;
import info.nightbrest.agt.shared.rpc.action.LoginAction;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Entry point for the Agt app.
 */
public class AgtApp implements ValueChangeHandler<String>,
		AgtShell.Presenter
{
	private static final Logger log           = Logger.getLogger(AgtShell.class.getName());
	private static final AgtInjector injector = GWT.create(AgtInjector.class);

	private static final String HOME_TOKEN         = "home";
	private static final String GAME_ARCHIVE_TOKEN = "archive";

	private final EventBus eventBus;
	private final AgtShell shell;
	private final AgtDispatcher dispatcher;

	public EventBus getEventBus()
	{
		return eventBus;
	}

	public AgtInjector getInjector()
	{
		return injector;
	}

	public AgtDispatcher getDispatcher()
	{
		return dispatcher;
	}

	public AgtApp()
	{
		dispatcher = injector.dispatcher();
		eventBus = new SimpleEventBus();
		shell = injector.shell();

		shell.setPresenter(this);
	}

	/**
	 * Initializes an app
	 * @return AgtApp
	 */
	public AgtApp init()
	{
		History.addValueChangeHandler(this);

		eventBus.addHandler(UserLoggedInEvent.TYPE, new UserLoggedInEvent.Handler()
		{
			@Override
			public void onUserLoggedIn(LoginAction.Response r) {
				Window.alert("Successfully logged in as: " + r.getUserFullName());
			}
		});

		return this;
	}

	/**
	 * Start the app, and add its main widget to the given panel.
	 * @param root
	 */
	public void go(HasWidgets root)
	{
		GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler()
		{
			public void onUncaughtException(Throwable e)
			{
				log.log(Level.SEVERE, e.getMessage(), e);
			}
		});

		root.add(shell.asWidget());

		new AuthPanelPresenter(injector.authPanelView()).init().go((HasWidgets) shell.getAuthPanel());
		new NewsFeedPresenter(injector.newsFeedView()).init().go((HasWidgets) shell.getRightPanel());
		new DocumentListPresenter(injector.documentListView()).init().go((HasWidgets) shell.getContentPanel());

	}

	@Override
	public void onValueChange(ValueChangeEvent<String> event)
	{
		String token = event.getValue();

		if (token == null || token.equals(HOME_TOKEN))
		{
		}
	}

	@Override
	public void doLogin()
	{
		LoginPanelView loginPanel = shell.getLoginPanel();
		dispatcher.action(new LoginAction(loginPanel.getLogin(), loginPanel.getPassword()),
						  new AsyncCallback<LoginAction.Result>()
		{
			@Override
			public void onFailure(Throwable caught)
			{
				//To change body of implemented methods use File | Settings | File Templates.
			}

			@Override
			public void onSuccess(LoginAction.Result result)
			{
				//To change body of implemented methods use File | Settings | File Templates.
			}
		});
	}
}
